#ifndef DICOMIMAGEVIEW_H
#define DICOMIMAGEVIEW_H

#include <QGraphicsView>
#include "viewshare.h"
class AbstractPathItem;
class GraphicsTumorItem;
class SeriesInstance;
class DicomImageLabel;
class DicomImage;
struct StudyRecord;
class QMenu;

class DicomImageView : public QGraphicsView
{
    Q_OBJECT
public:
    enum CurrentState {
        None,
        Zoom,
        Pan,
        Magnifier,
        ROIWindow,
        Drawing,
        ChooseSeed,
    };

    enum DrawingType {
        DrawLine,
        DrawAngle,
        DrawCobbAngle,
        DrawRect,
        DrawEllipse,
        DrawPolygon,
        DrawClosedCurve,
        DrawTextMark,
        DrawArrow,
        DrawCurve,
    };
    enum ViewMode {
        VM_Observe,
        VM_Print,
        VM_Report,
    };

    typedef struct tag_MouseButtonState {
        CurrentState state;
        DrawingType type;

        tag_MouseButtonState() { state = None; }
    } MouseButtonState;

    explicit DicomImageView(ViewType type = VT_XYPlane, SeriesInstance *series = 0, QWidget *parent = 0);
    ~DicomImageView();
    void setSeriesInstance(SeriesInstance *series);
    SeriesInstance *const getSeriesInstance() const { return series; }
    void setHighlight(bool yes);
    void setViewMode(ViewMode viewMode);
    void setSizeHint(const QSize &size) { hintSize = size; }
    bool hasSeries() { return series != 0; }
    DicomImage *getHardCopyGrayScaledImage();
    QImage getTextLayerImage(const QSize &size);
    QPixmap getHardCopyPixmap();
    QImage getRenderedTumorImage();
    void refreshViewPort() { refreshPixmap(); resizePixmapItem(); repositionAuxItems(); }
    void setAnnoTextFont(const QFont &font);
    int getFrameCount() const;
    bool getImageDimensions(int &x, int &y, int &z) const;
    bool getSeedValue(int x, int y, int z, int &val) const;
    const short **getSeriesVolume(const short **&volume, ulong &width, ulong &height, ulong &slice) const;
    const ushort **getRawVolume(const ushort **&volume, ulong &width, ulong &height, ulong &slice) const;
    bool getStudyRecord(StudyRecord &rec) const;

signals:
    void statusChanged(bool hasImage);
    void windowChanged();
    void viewClicked(DicomImageView *view);
    void viewDoubleclicked(DicomImageView *view);
    void seedChoosing(int x, int y, int z, int val, DicomImageView *view);
    void seedFinished(bool ok);
    void thumbnailDraggedIn(DicomImageLabel *label);

public slots:
    void showTumor(bool yes) { tumorOn = yes; updateTumorItem(); }
    void setMaskVolume(const uchar **mask, int start, int count) { maskVol = mask; maskStart = start; maskCount = count; updateTumorItem(); }
    void onSeedFinished(bool ok);
    void setSeedPos(int x, int y, int frame);
    void chooseSeed() { leftButton.state = ChooseSeed; seedSlice = -1; }
    void delVolBuffer();
    void updateImage() { refreshPixmap(); }
    void inverseImage();
    void setRoiWindow();
    void setNone();
    void rotateCCW();
    void rotateCW();
    void zoomImage();
    void magnifier();
    void hFlip();
    void vFlip();
    void panImage();
    void drawLenght();
    void drawAngle();
    void drawCobbAngle();
    void drawEllipse();
    void drawRectangle();
    void drawArrow();
    void drawText();
    void removeCurrent();
    void reset();
    void clear() { setSeriesInstance(0); }
    void saveFile();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *e);
    void leaveEvent(QEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);
    void resizeEvent(QResizeEvent *event);
    QSize sizeHint() const { return hintSize; }
    void dragEnterEvent(QDragEnterEvent *e);
    void dragMoveEvent(QDragMoveEvent *e);
    void dropEvent(QDropEvent *e);
    void contextMenuEvent(QContextMenuEvent *e);

private:
    void setupContextMenu();
    void setMagnifierPixmap(const QPointF &itemPos);
    void updateScalors();
    void updateAnnotations();
    inline void refreshPixmap();
    void resizePixmapItem();
    void repositionAuxItems();
    void setTextItemVisible(bool yes);
    void sendSeedInfo(int x, int y, int val);
    void updateTumorItem();

    QGraphicsScene *scene;
    SeriesInstance *series;

    QList<AbstractPathItem*> itemList;
    QGraphicsPixmapItem *pixmapItem;
    QGraphicsPixmapItem *subPixmapItem;
    QGraphicsPathItem *xScalorItem;
    QGraphicsPathItem *yScalorItem;
    QGraphicsPathItem *seedItem;
    GraphicsTumorItem *tumorItem;
    QGraphicsSimpleTextItem *posValue;
    QGraphicsSimpleTextItem *tlItem;
    QGraphicsSimpleTextItem *trItem;
    QGraphicsSimpleTextItem *blItem;
    QGraphicsSimpleTextItem *brItem;
    QGraphicsSimpleTextItem *windowItem;
    QGraphicsSimpleTextItem *zoomItem;
    QGraphicsSimpleTextItem *magFactorItem;

    QMenu *contextMenu;
    MouseButtonState leftButton;
    AbstractPathItem *currentPathItem;
    QPoint prevMousePos;
    QPoint prevPressedPos;
    double factor;
    double fixFactor;
    double magFactor;
    QSize hintSize;
    QCursor nullCursor;
    QFont annoFont;

    bool manualZoom;
    bool manualPan;
    int hflip;
    int vflip;
    int rotateAngle;
    int seedSlice;
    bool tumorOn;
    const uchar **maskVol;
    int maskStart;
    int maskCount;

    ViewMode mode;
    ViewType vType;
};

#endif // DICOMIMAGEVIEW_H
